'use strict';
var log = console.log.bind(console)

function getURLParams(url) {
    var urlParts = url.split("?");
    var result = {};
    if (urlParts[1]) {
        var params = urlParts[1].split("&");

        for (var i = 0; i < params.length; ++i) {
            var item = params[i].split("=");
            var key = decodeURIComponent(item[0]);
            var uri_encoded = item[1].replace(/%([^\da-fA-f].)/, "%25$1")
            var val = decodeURIComponent(uri_encoded);
            result[key] = val;
        }
    }
    return result;
}

function serializeParams(data) {
    var serializedParams = '';
    for (var pro in data) {
        serializedParams += (serializedParams.length ? '&' : '') + pro + '=' + encodeURIComponent(data[pro]);
    }
    return serializedParams;
}

function getParams(data, key, default_value) {
    if (data != undefined) {
        return key in data ? data[key] : default_value;
    }
    return default_value;
}

function isFunction(fn) {
    return typeof fn === 'function';
}

function defineReactive(obj, key, val, before_change, after_change, flags) {
    var blocking = false, setter, getter;
    flags = flags || 0; // 第1位 值一样的情况下是否触发
    if (val instanceof Object && isFunction(val.set) && isFunction(val.get)) {
        setter = val.set;
        getter = val.get;
    } else {
        getter = function () {
            return val;
        };
        setter = function (newVal) {
            val = newVal
        };
    }
    Object.defineProperty(obj, key, {
        enumerable: true,
        configurable: true,
        get: function reactiveGetter() {
            return getter.call(obj);
        },
        set: function reactiveSetter(newVal) {
            if (blocking) {
                return;
            }
            blocking = true;
            do {
                if (val === newVal && !(flags & 1)) {
                    break;
                }
                if (isFunction(before_change) && before_change.call(obj, val, newVal) === true) {
                    break;
                }
                var originVal = val;
                try {
                    setter.call(obj, newVal);
                    isFunction(after_change) && after_change.call(obj, originVal, val);
                } catch (e) {
                    blocking = false;
                    throw e;
                }
            } while (false);
            blocking = false;
        }
    });
}

function loadScript(url, fn, error) {
    var script = document.createElement("script");
    script.type = "text/javascript";
    if (script.readyState) {
        script.onreadystatechange = function () {
            if (script.readyState == "loaded" || script.readyState == "complete") {
                script.onreadystatechange = null;
                isFunction(fn) && fn();
            }
        };
    } else {
        script.onload = function () {
            isFunction(fn) && fn();
        };
        script.onerror = function () {
            isFunction(error) && error();
        }
    }
    script.src = url;
    document.body.appendChild(script);
}

function doAjax(args) {
    var request = new XMLHttpRequest(),
        url = getParams(args, 'url', ''),
        data = getParams(args, 'data', {}),
        contentType = getParams(args, 'contentType', "application/x-www-form-urlencoded"),
        type = getParams(args, 'type', 'get');

    request.onreadystatechange = function () {
        if (request.readyState == 4) {
            if (request.status == 200) {
                var dataType = null;
                if ('dataType' in args) {
                    dataType = args.dataType;
                } else {
                    if (/\bContent\-Type\s*:\s* ([^\n;]+)(?=\n|;)/i.test(request.getAllResponseHeaders())) {
                        var contentType = RegExp.$1;
                        if (/\bjson\b/i.test(contentType)) {
                            dataType = 'json';
                        } else {
                            dataType = 'text';
                        }
                    }
                }
                var data = null;
                if (/^json$/i.test(dataType)) {
                    data = JSON.parse(request.responseText);
                } else {
                    data = request.responseText;
                }
                try {
                    if (typeof args.success == 'function') {
                        args.success(data);
                    }
                } catch (e) {
                }
            } else {
                if (typeof args.error == 'function') {
                    args.error(request.status);
                }
            }
        }
    }
    request.onloadstart = function () {
        if (typeof args.loadstart == 'function') {
            args.loadstart();
        }
    }
    request.onprogress = function (event) {
        if (typeof args.progress == 'function') {
            args.progress(event);
        }
    }
    request.timeout = getParams(args, 'timeout', 0);

    if (/^post$/gi.test(type)) {
        request.open("POST", url, true);
        request.setRequestHeader("Content-Type", contentType);
        if ("application/x-www-form-urlencoded" == contentType) {
            var content = typeof data === 'string' ? data : serializeParams(data);
            request.send(content);
        } else if ("application/json" == contentType) {
            var content = typeof data === 'string' ? data : JSON.stringify(data);
            request.send(content);
        }

    } else {
        url += (url.indexOf("?") >= 0 ? '&' : '?') + serializeParams(data);
        request.open("GET", url, true);
        request.send();
    }
}

function doJsonAjax(url, data, success, failed, loadstart, progress) {
    doAjax({
        url: url,
        type: 'post',
        data: data,
        contentType: 'application/json',
        success: success,
        error: failed,
        loadstart: loadstart,
        progress: progress
    });
}

function extendMethod(class_name, method_set) {
    for (var method_name in method_set) {
        class_name.prototype[method_name] = method_set[method_name];
    }
}

function EventListener() {
}

extendMethod(EventListener, {
    on: function (event, func) {
        if (typeof event === 'string' && typeof func === 'function') {
            var list = this['on' + event + 'list'];
            if (list instanceof Array) {
                for (var i = 0; i < list.length; i++) {
                    if (list[i] === func) {
                        return this;
                    }
                }
                list.push(func);
            } else {
                this['on' + event + 'list'] = [func];
            }
        }
        return this;
    },

    off: function (event, func) {
        var list = this['on' + event + 'list'];
        if (list instanceof Array) {
            if (!func) {
                list.length && list.splice(0, list.length);
            } else {
                for (var i = 0; i < list.length; i++) {
                    if (list[i] === func) {
                        list.splice(i, 1);
                        break;
                    }
                }
            }
        }
        return this;
    },

    trigger: function (event) {
        var result = false, list = this['on' + event + 'list'];
        if (list instanceof Array) {
            for (var i = 0; i < list.length; i++) {
                var func = list[i];
                if (typeof func != 'function') {
                    continue;
                }
                var args = Array.prototype.slice.call(arguments, 0);
                args.shift();
                result = result || func.apply(this, args);
            }

        }
        return result;
    }
});

function __() {
    this.timer = 0;
    this.queue = [];
    this.complete = null;
}

__.prototype.then = function (cb, delay) {
    this.queue.push({callback: cb, delay: delay});
    return this;
}

__.prototype.end = function (cb) {
    this.complete = cb;
    return this;
}

__.prototype.abort = function () {
    if (this.timer) {
        clearTimeout(this.timer);
        this.timer = 0;
    }
    return this;
}

__.prototype.commit = function () {
    var self = this;
    if (this.queue.length && !this.timer) {
        var top = this.queue.shift();
        if (typeof top.callback == 'function') {
            if (typeof top.delay != 'number' || top.delay <= 0) {
                top.callback.apply(self);
                this.commit();
            } else {
                this.timer = setTimeout(function () {
                    top.callback.apply(self);
                    self.timer = 0;
                    self.commit();
                }, top.delay);
            }
        } else {
            self.commit();
        }
    } else if (!this.queue.length && !this.timer) {
        if (typeof this.complete == 'function') {
            this.complete.apply(this);
            this.complete = null;
        }
    }
    return this;
}

function then(cb, delay) {
    return (new __()).then(cb, delay);
}

$(function () {
    document.body.addEventListener('touchstart', function () {
    });
});

var cookie = {
    set: function (key, val, dur) {//设置cookie方法
        var now = new Date(); //获取当前时间
        now.setDate(now.getDate() + dur);
        document.cookie = key + '=' + val + ';expires=' + now + ";path=/";
    },
    get: function (key) {//获取cookie方法
        /*获取cookie参数*/
        var getCookie = document.cookie.replace(/[ ]/g, "");  //获取cookie，并且将获得的cookie格式化，去掉空格字符
        var arrCookie = getCookie.split(";")  //将获得的cookie以"分号"为标识 将cookie保存到arrCookie的数组中
        var tips;  //声明变量tips
        for (var i = 0; i < arrCookie.length; i++) {   //使用for循环查找cookie中的tips变量
            var arr = arrCookie[i].split("=");   //将单条cookie用"等号"为标识，将单条cookie保存为arr数组
            if (key == arr[0]) {  //匹配变量名称，其中arr[0]是指的cookie名称，如果该条变量为tips则执行判断语句中的赋值操作
                tips = arr[1];   //将cookie的值赋给变量tips
                break;   //终止for循环遍历
            }
        }
        return tips;
    },
    del: function (key) {
        cookie.set(key, '', -1)
    }
};